/**
 * 
 */
package cn.edu.cqu.bysj.wm.gui.result;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.neo4j.graphdb.Direction;
import org.neo4j.graphdb.Node;

import cn.edu.cqu.bysj.wm.ago.anlys.Similarity;
import cn.edu.cqu.bysj.wm.ago.gn.GNRun;
import cn.edu.cqu.bysj.wm.ago.lp.LPRun;
import cn.edu.cqu.bysj.wm.def.ConstDef.AlgorithmType;
import cn.edu.cqu.bysj.wm.def.ConstDef.ConfigType;
import cn.edu.cqu.bysj.wm.def.ConstDef.KeyNodeType;
import cn.edu.cqu.bysj.wm.def.Weight;
import cn.edu.cqu.bysj.wm.gui.model.AlgorithmConfig;
import cn.edu.cqu.bysj.wm.gui.model.AlgorithmResult;
import cn.edu.cqu.bysj.wm.gui.model.SQJDAlgorithm;
import cn.edu.cqu.bysj.wm.keynode.KeyNodes;

/**
 * @author Meng
 * 
 */
public class ExecuteAlgorithm implements SQJDAlgorithm {

	@Override
	public AlgorithmResult execute(AlgorithmConfig config) {
		// communtiy detection
		if (config.getType().equals(ConfigType.SQ)) {
			// use GN algorithm
			if (config.getAlgorithmType().equals(AlgorithmType.GN)) {
				Weight weight = config.getWeight();
				GNRun.runGN(config.getFilePath(), weight);
				return DetectedResult.getGNAlgorithmResult();
			}
			// use LP algorithm
			if (config.getAlgorithmType().equals(AlgorithmType.LP)) {
				Weight weight;
				Direction direction;
				weight = config.getWeight();
				direction = config.getDirection();
				if (config.getTime() == 1) {
					LPRun.runLP(config.getFilePath(), weight, direction);
					return DetectedResult.getLPAlgorithmResult();
				} else {
					// run LP algorithm for more than 1 time
					Similarity.solutions = new HashMap<Integer, Map<Long, List<Node>>>();
					Similarity.Qs = new HashMap<Integer, Double>();
					Similarity.SID = 0;
					for (int i = 0; i < config.getTime(); i++) {
						LPRun.runLP(config.getFilePath(), weight, direction);
						if (i != config.getTime() - 1) {
							LPRun.closeDbService();
						}
					}
					Similarity.calcFJ();
					return DetectedResult.getSolutionsResult();
				}
			}
		}
		// key node detection
		if (config.getType().equals(ConfigType.JD)) {
			KeyNodes.flag = config.getFlag();
			// global key node detection
			if (config.getKeyNodeType().equals(KeyNodeType.GLOBAL)) {
				// use Fagin algorithm
				if (config.getAlgorithmType().equals(AlgorithmType.FAGIN)) {
					KeyNodes.faginGlobalKeyNodes(config.getLp(),
							config.getTopK());
				}
				// use Skyline alorithm
				if (config.getAlgorithmType()
						.equals(AlgorithmType.SKYLINE)) {
					KeyNodes.skylineGlobalKeyNodes(config.getLp());
				}
				return DetectedResult.getGlobalKeyNodeResult();
			}
			// local key node detection
			if (config.getKeyNodeType().equals(KeyNodeType.LOCAL)) {
				// use Fagin algorithm
				if (config.getAlgorithmType().equals(AlgorithmType.FAGIN)) {
					KeyNodes.faginLocalKeyNodes(config.getLp(),
							config.getPercent());
				}
				// use Skyline alorithm
				if (config.getAlgorithmType()
						.equals(AlgorithmType.SKYLINE)) {
					KeyNodes.skylineLocalKeyNodes(config.getLp());
				}
				return DetectedResult.getLocalKeyNodeResult();
			}
		}
		return null;
	}
}
